﻿
using Best.SmartCms.API.Filters;
using Best.SmartCms.API.WebAPIExtensions;
using Best.SmartCms.Domain;
using Best.SmartCms.Service.Common;
using Best.SmartCms.Utility.JsonFormater;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpOverrides;
using Microsoft.AspNetCore.StaticFiles;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Tokens;
using System.IO;
using System.Text;
using Best.SmartCms.Config;
using NLog.Extensions.Logging;
using NLog.Web;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Mvc.Authorization;
using Swashbuckle.AspNetCore.SwaggerUI;

namespace Best.SmartCms.API
{
    /// <summary>
    /// 
    /// </summary>
    public class Startup
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="configuration"></param>
        /// <param name="hostingEnvironment"></param>
        public Startup(IConfiguration configuration, IWebHostEnvironment hostingEnvironment)
        {
            Configuration = configuration;
            HostingEnvironment = hostingEnvironment;
        }

        /// <summary>
        /// 
        /// </summary>
        public IConfiguration Configuration { get; }

        /// <summary>
        ///
        /// </summary>
        public IWebHostEnvironment HostingEnvironment { get; }

        /// <summary>
        /// This method gets called by the runtime. Use this method to add services to the container.
        /// </summary>
        /// <param name="services"></param>
        public void ConfigureServices(IServiceCollection services)
        {
            string connectionString = Configuration.GetConnectionString("MySqlConnectionString");
            services.AddDbContext<MySqlDbContext>(options =>
                {
                    options.UseMySql(connectionString, b => b.MigrationsAssembly("Best.SmartCms.API"));
                }
            );

            services.AddServices();
            services.AddMemoryCache();

            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                .AddJwtBearer(options =>
                {
                    var issuer = ConfigurationManagerEx.AppSettings["Auth:JwtIssuer"];
                    var key = ConfigurationManagerEx.AppSettings["Auth:JwtKey"];
                    options.RequireHttpsMetadata = false;
                    options.SaveToken = true;
                    options.TokenValidationParameters = new TokenValidationParameters()
                    {
                        ValidIssuer = issuer,
                        ValidAudience = issuer,
                        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(key)),
                        ValidateIssuer = true,
                        ValidateIssuerSigningKey = true,
                        ValidateLifetime = true,
                    };
                });

            //添加Swagger
            services.AddSwaggerGen(options =>
            {
                options.SwaggerDoc("v1", new Microsoft.OpenApi.Models.OpenApiInfo { Title = "SmartCms API Document", Version = "v1" });
            });

            services.AddControllers(option =>
            {
                // option.EnableEndpointRouting = false; // app.UseMvc();
                option.Filters.Add(typeof(ExceptionFilter));
                option.Filters.Add(typeof(TokenAuthorizeAttribute));
                //option.Filters.Add(new ActionSignatureAttribute());
                option.Filters.Add(typeof(ModelValidationFilter));
            }).AddNewtonsoftJson(option =>
            {
                option.SerializerSettings.ContractResolver = new CustomizeDefaultResolver();
                option.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
            });
        }

        /// <summary>
        /// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        /// </summary>
        /// <param name="app"></param>
        /// <param name="env"></param>
        /// <param name="loggerFactory"></param>
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            // Set up custom content types - associating file extension to MIME type
            var provider = new FileExtensionContentTypeProvider();
            // Add new mappings
            provider.Mappings[".htm3"] = "text/html";

            app.UseStaticFiles(new StaticFileOptions
            {
                FileProvider = new PhysicalFileProvider(
                    Path.Combine(Directory.GetCurrentDirectory(), "wwwroot")),
                RequestPath = new PathString("/files"),
                ContentTypeProvider = provider
            });

            app.UseHttpsRedirection();

            app.UseRouting();
            // 注册Nlog
            loggerFactory.AddNLog();
            env.ConfigureNLog("NLog.config");

            app.UseForwardedHeaders(new ForwardedHeadersOptions { ForwardedHeaders = ForwardedHeaders.All });
            app.UseAuthentication();
            app.UsePathBase("/cmsapi");
            // app.UseMvc(); 2.2 版本.
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            }); // 3.1 版本

            //启用中间件服务生成Swagger作为JSON终结点
            app.UseSwagger(c => { c.RouteTemplate = "swagger/{documentName}/swagger.json"; });
            //启用中间件服务对swagger-ui，指定Swagger JSON终结点
            app.UseSwaggerUI(c =>
            {
                c.SwaggerEndpoint("v1/swagger.json", "ProjectFlowMangement10WebApi API"); c.RoutePrefix = "swagger";
                c.DocExpansion(DocExpansion.None);
                c.DefaultModelsExpandDepth(-1);
            });
        }


    }
}
